package com.zcx.excel.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.fastjson.JSON;
import com.zcx.excel.common.vo.ApiResult;
import com.zcx.excel.pojo.Price;
import com.zcx.excel.pojo.PriceExample;
import com.zcx.excel.service.PriceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author zhaochangxin
 * @Title: EasyExcelController
 * @Package com.zcx.excel.controller
 * @Description: 测试阿里巴巴EasyExcel
 * @date 2022/3/28 10:51
 */
@RequestMapping("/easyExcel")
@RestController
@Slf4j
public class EasyExcelController {
    @Autowired
    PriceService priceService;

    /**
     * 　* @author zhaochangxin
     * 　* @Description:导出Excel
     * 　* @Param priceExample:
     * 　* @return: com.zcx.excel.common.vo.ApiResult
     * 　* @date 2022/3/28 11:58
     * 　* @throws
     *
     */
    @RequestMapping("/toExcel")
    public ApiResult EasyExcelToExcel(PriceExample priceExample) {
        int[] num = new int[5];

        long start = System.currentTimeMillis();
        PriceExample.Criteria criteria = priceExample.createCriteria();
        criteria.andCreatedByIsNotNull();
        String fileName = "D:\\Tesla\\test\\" + "test" + System.currentTimeMillis() + ".xlsx";
        // 这里 需要指定写用哪个class去写，然后写到第一个sheet，名字为模板 然后文件流会自动关闭
        // 如果这里想使用03 则 传入excelType参数即可
        EasyExcel.write(fileName, Price.class).sheet("模板").doWrite(priceService.queryAllPriceList(priceExample));
        long end = System.currentTimeMillis();
        System.out.println("EasyExcel导出所用时间:" + (end - start));
        return ApiResult.success("EasyExcel导出成功");
    }

    /**
     * 　* @author zhaochangxin
     * 　* @Description:导入Excel并插入数据
     * 　* @return: com.zcx.excel.common.vo.ApiResult
     * 　* @date 2022/3/28 11:58
     * 　* @throws
     *
     */
    @RequestMapping("/addFromExcel")
    public ApiResult PriceAddFromExcel() {
        long start = System.currentTimeMillis();
        String fileName = "D:\\Tesla\\test\\test1648452751022" + ".xlsx";
        EasyExcel.read(fileName, Price.class, new PageReadListener<Price>(priceList -> {
            for (Price price : priceList) {
                priceService.insertPrice(price);
                log.info("读取到一条数据{}", JSON.toJSONString(price));
            }
        })).sheet().doRead();
        long end = System.currentTimeMillis();
        System.out.println("EasyExcel导入所用时间:" + (end - start));
        return ApiResult.success("EasyExcel导入成功", "执行所用时间:" + (end - start));
    }

    /**
     * 最简单的填充
     *
     * @since 2.1.1
     */
    @RequestMapping("/template")
    public ApiResult simpleFill(PriceExample priceExample) {
        PriceExample.Criteria criteria = priceExample.createCriteria();
        criteria.andCreatedByIsNotNull();
        // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
        // {} 代表普通变量 {.} 代表是list的变量
        String templateFileName =
                "D:\\Tesla\\test\\" + "1.xlsx";

        /**
         　* @author zhaochangxin
         　* @Description:最简单的填充 根据对象填充
         　*/

//        String fileName = "D:\\Tesla\\test\\" + "simpleFill" + System.currentTimeMillis() + ".xlsx";
        // 这里 会填充到第一个sheet， 然后文件流会自动关闭
//        EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(price);

        /**
         　* @author zhaochangxin
         　* @Description:填充列表 List 一下子全部放到内存里面 并填充
         　*/

//        String fileName = "D:\\Tesla\\test\\" + "listFill" + System.currentTimeMillis() + ".xlsx";
        // 这里 会填充到第一个sheet， 然后文件流会自动关闭
//        EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(priceService.queryAllPriceList(priceExample));

        /**
         　* @author zhaochangxin
         　* @Description:复杂的填充
         　*/

        String fileName = "D:\\Tesla\\test\\" + "complexFill" + System.currentTimeMillis() + ".xlsx";
        ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行，然后下面的数据往后移动。默认 是false，会直接使用下一行，如果没有则创建。
        // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了，所以慎用
        // 简单的说 如果你的模板有list,且list不是最后一行，下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
        // 如果数据量大 list不是最后一行 参照下一个
        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
        excelWriter.fill(priceService.queryAllPriceList(priceExample), fillConfig, writeSheet);
        excelWriter.fill(priceService.queryAllPriceList(priceExample), fillConfig, writeSheet);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("date", "2022年3月29日16:48");
        excelWriter.fill(map, writeSheet);
        excelWriter.finish();

        return ApiResult.success();

    }

}
